package com.wan37.logic.listener.handler;

import com.wan37.logic.db.AsynDBManager;
import com.wan37.logic.domain.entity.RoleDO;
import com.wan37.logic.domain.entity.UserItemDO;
import com.wan37.logic.domain.entity.UserSkillDO;
import com.wan37.logic.domain.entity.UserWeaponryDO;
import com.wan37.logic.global.reference.SpringContextHolder;
import com.wan37.logic.handler.server.AutoAddHpHandler;
import com.wan37.logic.listener.annotation.EventHandler;
import com.wan37.logic.listener.annotation.Listener;
import com.wan37.logic.listener.event.EventType;
import com.wan37.logic.listener.event.user.UserLogoutEvent;
import com.wan37.logic.service.UserItemService;
import com.wan37.logic.service.RoleService;
import com.wan37.logic.service.UserSkillService;
import com.wan37.logic.service.UserWeaponryService;
import com.wan37.logic.service.cache.RoleServiceCache;
import com.wan37.logic.service.cache.UserServiceCache;
import com.wan37.logic.utils.DelayDequeThreadPollUtil;
import com.wan37.logic.utils.RoleLevelUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author : luoyong
 * @date : 2020-06-29 15:34
 **/
@Listener
public class RoleListenerHandler {
    private final static Logger logger = LoggerFactory.getLogger(RoleListenerHandler.class);
    private UserSkillService userSkillService;
    private RoleService roleService;
    private RoleServiceCache roleServiceCache;
    private UserServiceCache userServiceCache;
    private UserItemService userItemService;
    private UserWeaponryService userWeaponryService;
    private DelayDequeThreadPollUtil delayDequeThreadPollUtil;
    private RoleLevelUtil roleLevelUtil;
    private AsynDBManager asynDBManager;

    public RoleListenerHandler() {
        this.userSkillService = SpringContextHolder.getBean("userSkillService");
        this.roleService = SpringContextHolder.getBean("roleService");
        this.roleServiceCache = SpringContextHolder.getBean("roleServiceCache");
        this.userServiceCache = SpringContextHolder.getBean("userServiceCache");
        this.userItemService = SpringContextHolder.getBean("userItemService");
        this.userWeaponryService = SpringContextHolder.getBean("userWeaponryService");
        this.delayDequeThreadPollUtil = SpringContextHolder.getBean("delayDequeThreadPollUtil");
        this.roleLevelUtil = SpringContextHolder.getBean("roleLevelUtil");
        this.asynDBManager = SpringContextHolder.getBean("asynDBManager");
    }

    @EventHandler(value = EventType.LOGOUT)
    public void logout(UserLogoutEvent userLogoutEvent) {
        String userId = userLogoutEvent.getUserId();
        userServiceCache.getUserServiceMap().get(userId)
                .getRoleIdList().forEach(roleId -> {
            RoleServiceCache.Role role = roleServiceCache.getRoleServiceMap().get(roleId);

            //技能更新
            role.getSkillVOMap().values().forEach(skillVO -> {
                UserSkillDO userSkillDO = new UserSkillDO();
                userSkillDO.setUserId(userId);
                userSkillDO.setSkillId(skillVO.getId());
                userSkillDO.setLevel(skillVO.getLevel());
                userSkillDO.setUsage(skillVO.getUsage());
                asynDBManager.distributeWork(userId, () -> userSkillService.update(userSkillDO));
            });

            RoleDO roleDO = new RoleDO(role.getRoleVO());
            asynDBManager.distributeWork(userId, () -> roleService.update(roleDO));
            //关闭用户的自动回复hp线程
            delayDequeThreadPollUtil.stop(delayDequeThreadPollUtil.getScheduledFutureMapKey(roleId, AutoAddHpHandler.class.getSimpleName()));
            //将角色从列表中删除
            roleServiceCache.getRoleServiceMap().remove(roleId);
        });
        UserServiceCache.User user = userServiceCache.getUserServiceMap().get(userId);
        user.getItemVOMap().values().forEach(itemVO -> {
            UserItemDO userItemDO = new UserItemDO();
            userItemDO.setUserId(userId);
            userItemDO.setItemId(itemVO.getBackpackId());
            userItemDO.setCount(itemVO.getCount());
            asynDBManager.distributeWork(userId, () -> userItemService.update(userItemDO));
        });

        user.getWeaponryVOMap().values().forEach(weaponryVO -> {
            UserWeaponryDO userWeaponryDO = new UserWeaponryDO(weaponryVO);
            userWeaponryDO.setUserId(userId);
            asynDBManager.distributeWork(userId, () -> userWeaponryService.update(userWeaponryDO));
        });
    }
}
